home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Plug-In Power Pack for Netscape Communicator
/
Plug-In Power Pack for Netscape Communicator.iso
/
plugins
/
dataviews
/
include
/
vupixrep.h
< prev
next >
Wrap
Text File
|
1997-05-08
|
25KB
|
721 lines
/*
static char SccsId[]="@(#)VUpixrep.h V1.10 3/16/95";
*/
/*
| file name -- VUpixrep.h
|===================================================================
|
| V.I. Corporation
| Copyright (c) 1991
|
| VUpixrep.h - structures and macros for use with pixreps
|
| Chris Hoffmann --- 10 Oct 1991
|
|===================================================================
|
| Module description/function:
| This module defines the pixrep structure as well as macros for
| examining color components of a pixrep's pixel values. It also defines
| a structure based on a pixrep called a pixscan. A pixscan contains
| the necessary information to read a pixrep as a consecutive stream of
| pixel values. A set of macros are provided to allow this reading to be
| done easily.
|
| PIXREPS
| A pixrep is an abstract representation of pixel-based graphic data.
| The pixels are considered to be arranged in a rectangular array,
| however, there is quite a bit of flexibility in the actual layout of
| the pixels in the array and in what how the actual pixel values are
| interpreted. The hope is that the pixrep format is general enough to
| be a superset of most raster/pixel formats we must deal with.
| A set of macros are provided to make it easy to read through the
| pixels in a pixrep regardless of its internal format. There are also
| functions for modifying a pixrep in various ways.
|
| The layout of the actual pixel data array is controlled by certain
| fields in the pixrep. What follows is a description of the allowable
| variations in the layout. See the actual structure for the names of
| the fields that control each attribute.
|
| First the pixrep must indicate the height and width of the data in
| pixels. The pixels are given as a single vector of data. The pixels
| in this vector are arranged in rows, in left-to-right order.
| The data can be arranged so the bottom row of the picture is
| first in the array (this is the VI row order) or the top row is the
| first (this is the order used by X and SunView). Each pixel in the row takes
| up a certain number of bits. This number can be 1, 2, 4, 8, 16, or 32.
| Generally, if the actual depth of the picture is less than the number of
| bits per pixel, the data is stored in the least significant part of
| those bits (for example, if the picture has depth 1 but for some
| reason we were using a byte for each pixel, the low-order bit of
| the byte contains the pixel value). See the description of
| "direct-color" pixreps for exceptions to this.
|
| Rows can be aligned on 8, 16 or 32 bit boundaries. If on 8-bit
| boundaries, rows are consecutive in memory. If on 16-bit, each row
| starts on the next even address after the last byte of the previous
| row. Similar is the 32-bit case, where rows start on the first address
| divisible by 4 after the last unused byte.
|
| If the there are fewer than 8 bits per pixel, the data is packed into
| an 8, 16, or 32 bit unit. Within a unit, the pixels can be entered
| into either the least-significant or the most-signficant bytes of the
| unit first. Additionally, within each byte of the unit, the pixels
| can be packed in in MSB or LSB order. If the pack unit is 8, the unit
| packing order is irrelevant.
|
| To help make this packing order business clearer, suppose the start of
| the first row in a 1-bit picture looks like the following:
|
| 0011 0111 0000 1101 1100 1010 1001 1000 (spaces added for clarity)
|
| Here is how this pattern would be represented in the first two bytes
| of a few 1-bit deep pixreps with various formats:
|
| pack-unit = 8, pack_msf_in_byte = YES, pack_msf_in_unit = either.
| 0x370D 0xCA98
| pack-unit = 8, pack_msf_in_byte = NO, pack_msf_in_unit = either.
| 0xCE0B 0x3591 (this is X's bitmap format)
| pack-unit = 16, pack_msf_in_byte = YES, pack_msf_in_unit = YES.
| 0x370D 0xCA98 (this is SunView 680x0 bitmap format)
| pack-unit = 16, pack_msf_in_byte = YES, pack_msf_in_unit = NO.
| 0x0D37 0x98CA
| pack-unit = 16, pack_msf_in_byte = NO, pack_msf_in_unit = NO.
| 0xB0EC 0x1953 (this is SunView I386 bitmap format)
| pack-unit = 16, pack_msf_in_byte = NO, pack_msf_in_unit = YES.
| 0xECB0 0x5319
| pack-unit = 32, pack_msf_in_byte = YES, pack_msf_in_unit = YES.
| 0x370D 0xCA98
| pack-unit = 8, pack_msf_in_byte = NO, pack_msf_in_unit = NO.
| 0x1953 0xBEOC
|
| A row is always an integral multiple of the pack unit long. When
| determining the number of bytes per row, first figure the size by
| finding the number of pack units required, then add additional bytes
| as necessary to satisfy the row alignment.
|
| Unused bits between
| the end of one row and the start of the next may have any value. If
| there are more than 8 bits per pixel, the byte order in each pixel is
| the native order.
|
| There are two possible formats for the pixel values: they may be
| either "indirect-color" or "direct-color". Indirect-color pixel values
| are indices into a color table; direct-color store actual
| red/green/blue component values.
|
| If a pixrep points to a color table, the pixel values must be
| indirect-color. Since a color table has at most 256 entries, the depth
| of the pixrep can't be greater than 8. A pixrep can optionally contain
| a pointer to a boolean vector (of length 256) indicating which colors
| in the color table are actually used by the pixrep. Knowing this can
| potentially speed up some pixrep operations, particularly converting
| pixreps to rasters.
|
| If the color table pointer field is NULL, the pixrep must be
| direct-color. In this case there are three masks indicating where each
| component color is stored in a pixel. Components may be located
| anywhere in the pixel, but each component must occupy consecutive
| bits. For example, in a typical 24-bit color system each pixel is
| 32-bits long, where the most-significant byte is unused, the next byte
| contains red intensity, the third byte the green and the last byte the
| blue. This layout would be indicated by having a red mask of
| 0x00FF0000, a green mask of 0x00FF00, and a blue mask of 0x000000FF.
| For efficiency's sake, a pixrep also stores where the right-most "1"
| bit of each mask is located.
|
| PIXSCANS
| Pixscans are an easy way to access pixels in a pixrep. Using a
| pixscan, pixels from a pixrep can be read and written, in either row or
| column order, as a continuous stream of pixels. The current location
| in the pixrep can be changed at any time. A pixrep can be shared by
| any number of pixscans all reading and writing to different portions
| of the pixrep.
|
|
|
| ------------------------------------------------------------------
| Module contents:
| Macro Name Description
| ------------- -------------------------------
| GETREDPXRP Get the red component from a direct-color pixel value
| GETGRNPXRP " " green "
| GETBLUPXRP " " blue "
| PUTREDPXRP Put the red component into a direct-color pixel value
| PUTGRNPXRP " " green "
| PUTBLUPXRP " " blue "
| PIXPXRP Create a pixel value from all three components
| PIXSCALE Scale component to different range
| GETREDSTD Get the red component from a VI standard 24-bit pixel
| GETGRNSTD " " green "
| GETBLUSTD " " blue "
| PUTREDSTD Put the red component into a VI standard 24-bit pixel
| PUTGRNSTD " " green "
| PUTBLUSTD " " blue "
| PIXSTD Create a standard pixel value from all three components
| ISPIXSTD Is the pixel value in standard VI format?
|
| PXSCANPOINT Make a given pixel the next pixel to be read
| PXSCANREAD Read the current pixel and advance pixscan pointer
| PXSCANWRITE Write to the current pixel and advance pointer
| PXSCANREADL Read in left-to-right, bottom-to-top order
| PXSCANREADR Read in right-to-left, top-to-bottom order
| PXSCANREADD Read in top-to-bottom, left-to-right order
| PXSCANREADU Read in bottom-to-top, left-to-right order
| PXSCANWRITER Write in left-to-right, bottom-to-top order
| PXSCANWRITER Write in right-to-left, top-to-bottom order
| PXSCANWRITED Write in top-to-bottom, left-to-right order
| PXSCANWRITEU Write in bottom-to-top, left-to-right order
|
|====================================================================
*/
#ifndef VIPXRP
#define VIPXRP
#include "std.h"
#include "dvstd.h"
/* Module Include Files: */
#include "std.h"
#include "dvstd.h"
#include "dverrors.h"
/* Module Structure Definitions: */
/* the actual pixrep structure typedef is in the file dvstd.h */
#if 0
typedef struct
{
int width, height; /* width and height in pixels */
UBYTE depth; /* number of bits of color information */
UBYTE bits_per_pixel; /* 1,2,4,8,16,32 bits */
UBYTE row_alignment; /* 8,16,32==Rows aligned on char,short,LONG */
DV_BOOL origin_at_ll; /* is origin in lower-left? */
UBYTE pack_unit; /* if bits/pixel < 8, packing unit */
DV_BOOL pack_msf_in_byte; /* if bits/pixel < 8, order of pixels in byte */
DV_BOOL pack_msf_in_unit; /* if bits/pixel < 8, order of bytes in unit */
LONG pixels_length; /* length of pixel array */
UBYTE *pixels; /* actual pixels */
/* if (pclut != NULL), pixels are index into color table (*pclut) */
COLOR_TABLE *pclut;
DV_BOOL *color_used; /* which colors actually used (if known) */
/* if (pclut == NULL), pixels are direct color: */
ULONG red_mask;
int red_shift;
ULONG grn_mask; /* For green component of pixel, calculate */
int grn_shift; /* ((pixel & grn_mask) >> grn_shift) */
ULONG blu_mask;
int blu_shift; /* & similarly for red and blue components */
} PIXREP;
#endif
/* enum for function VUpxFlip() */
typedef enum
{
V_PX_HORIZONTAL, /* flip over horizontal axis */
V_PX_VERTICAL /* flip over vertical axis */
} V_PX_FLIP_ENUM;
/* enum for function VUpxMerge() */
typedef enum
{
V_PX_COPY, /* copy source to target */
V_PX_AND, /* and source and target */
V_PX_OR, /* or source and target */
V_PX_XOR /* xor source and target */
} V_PX_MERGEMODE_ENUM;
/*------------------------ pixrep pixel macros ---------------------------- */
/*
| Macros for getting color information from direct-color pixreps.
| In all cases, the colors are in the scale of the pixrep. That is,
| if the red component is 3 bits wide, then the component values
| must be in the range 0..7.
|
| Arguments:
| pix -- a pixel value read from a pixrep
| pr -- the pixrep that the pixel was read from
*/
#define GETREDPXRP( pix, pr ) (((pix) & (pr).red_mask) >> (pr).red_shift)
#define GETGRNPXRP( pix, pr ) (((pix) & (pr).grn_mask) >> (pr).grn_shift)
#define GETBLUPXRP( pix, pr ) (((pix) & (pr).blu_mask) >> (pr).blu_shift)
#define PUTREDPXRP( pix, r, pr ) ( ( (pix) & ~(pr).red_mask ) | \
( ((r) << (pr).red_shift) & (pr).red_mask) )
#define PUTGRNPXRP( pix, g, pr ) ( ( (pix) & ~(pr).grn_mask ) | \
( ((g) << (pr).grn_shift) & (pr).grn_mask) )
#define PUTBLUPXRP( pix, b, pr ) ( ( (pix) & ~(pr).blu_mask ) | \
( ((b) << (pr).blu_shift) & (pr).blu_mask) )
/*
| Macro to build a pixrep pixel value from the three color components.
| Again, the red, green, blue components must be already scaled
| Arguments:
| r, g, b -- color components to use when creating pixel
| pr -- the pixrep defining the pixel format
*/
#define PIXPXRP( r, g, b, pr ) ((((r) << (pr).red_shift) & (pr).red_mask) | \
(((g) << (pr).grn_shift) & (pr).grn_mask) | \
(((b) << (pr).blu_shift) & (pr).blu_mask) )
#define PIXSCALE( p, bs, bt ) (((bs)==(bt)) ? \
(p) : \
((bs)>(bt)) ? \
((p)>>((bs)-(bt))) : \
(((p)<<((bt)-(bs))) + \
((1<<((bt)-((bs)+1)))-1) \
) \
)
/* macros for performing the equivalent actions on a pixel in "standard"
| 24-bit RGB format.
*/
#define GETREDSTD( p ) ( ((p) & 0xFF0000) >> 16)
#define GETGRNSTD( p ) ( ((p) & 0x00FF00) >> 8)
#define GETBLUSTD( p ) ( ((p) & 0x0000FF) )
#define PUTREDSTD( p, r ) ( ((p) & 0x00FFFF) | (((r) << 16) & 0xFF0000) )
#define PUTGRNSTD( p, g ) ( ((p) & 0xFF00FF) | (((g) << 8) & 0x00FF00) )
#define PUTBLUSTD( p, b ) ( ((p) & 0xFFFF00) | (((r) ) & 0x0000FF) )
#define PIXSTD( r, g, b ) ( (((r) << 16) & 0xFF0000) | \
(((g) << 8) & 0x00FF00) | \
(((r) ) & 0x0000FF) | \
0x1000000 )
/* determines whether a pixel value is in standard format */
#define ISPIXSTD( p ) ( (p) & 0x1000000 )
/*------------------------ pixscan macros ---------------------------- */
/*
| These macros are used to efficiently read pixels, in order, from
| a pixrep. To do this two "private" structures are needed: a
| "pixscan" and a "pixptr".
|
| The following types hold for all the macros:
| pxrp is a PIXREP. Not a pointer to a PIXREP, but a PIXREP.
| If all you have is a PIXREP ptr, dereference it
| with "*".
|
| pxscan is a PIXSCAN. Not a pointer to a PIXSCAN.
|
| pixptr is a PIXPTR. You may want to declare this
| a register variable.
|
| source_pixel, target_pixel are ULONG
|
| Macros:
| -------
| PXSCANPOINT(pxrp, pxscan, pixptr, x, y)
| PXSCANREAD(target_pixel, pxrp, pxscan, pixptr )
| PXSCANWRITE( pxrp, pxscan, pixptr, source_pixel )
| PXSCANREADL(target_pixel, pxrp, pxscan, pixptr )
| PXSCANREADR(target_pixel, pxrp, pxscan, pixptr )
| PXSCANREADD(target_pixel, pxrp, pxscan, pixptr )
| PXSCANREADU(target_pixel, pxrp, pxscan, pixptr )
| PXSCANWRITEL( pxrp, pxscan, pixptr, source_pixel )
| PXSCANWRITER( pxrp, pxscan, pixptr, source_pixel )
| PXSCANWRITED( pxrp, pxscan, pixptr, source_pixel )
| PXSCANWRITEU( pxrp, pxscan, pixptr, source_pixel )
|
| To initialize a pixscan, call VUpxScanInit.
| The pixscan is pointing at pixel (0,0). That is, that is the
| first pixel that will be read. Rows can be numbered either
| in with origin at lower-left (row 0 is bottom row) or upper-right
| (row 0 is top row).
|
| To point the pixscan at some other pixel, use PXSCANPOINT.
| Remember that the order the rows are numbered depends on
| what row-order you specified when you created the pixscan.
|
| Read a pixel with PXSCANREAD. The value of the current pixel
| is put in target_pixel and the pixscan is set to point to the next
| pixel to the right. At the end of a row, the pixscan is set to point at
| the left-most pixel of the next-higher-numbered row (upwards if
| origin in lower-left, downwards otherwise).
|
| Write a pixel value with PXSCANWRITE. source_pixel is written at the
| current point in the pixscan and the pointer is adjusted as
| in PXSCANREAD.
|
| PXSCANREADL reads the pixscan in left to right, increasing row
| order (the same order as PXSCANREAD).
| PXSCANREADR reads the pixscan right to left, increasing row order
| PXSCANREADU reads the pixscan decreasing row, left to right col
| order ("DOWN" a column instead of ACROSS a row)
| PXSCANREADD reads the pixscan increasing row, left to right col
| order ("UP" a column instead of ACROSS a row)
|
| Similarly for PXSCANWRITE{L,R,U,D}
|
|
*/
#define PXSCANREADL(target_pixel, pxrp, pxscan, pixptr ) PXSCANREAD(target_pixel, pxrp, pxscan, pixptr )
#define PXSCANREAD(target_pixel, pxrp, pxscan, pixptr ) \
do \
{ \
if ((pxscan).iCol == (pxrp).width) \
{ \
PXSCANROWS(pxrp, pxscan, pixptr) \
} \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
(target_pixel) = *(pixptr).pul++; \
break; \
case 16: \
(target_pixel) = (unsigned short)*((pixptr).pus++); \
break; \
case 8: \
(target_pixel) = (UBYTE)*((pixptr).pub++); \
break; \
default: \
(target_pixel) = (*(pixptr).pub >> (pxscan).shift_array[(pxscan).bit_offset]) & (pxscan).read_mask; \
PXSCANBITI( pxrp, pxscan, pixptr ) \
} \
(pxscan).iCol += 1; \
} \
while(0)
#define PXSCANWRITEL( pxrp, pxscan, pixptr, source_pixel ) PXSCANWRITE( pxrp, pxscan, pixptr, source_pixel )
#define PXSCANWRITE( pxrp, pxscan, pixptr, source_pixel ) \
do \
{ \
if ((pxscan).iCol == (pxrp).width) \
{ \
PXSCANROWS(pxrp, pxscan, pixptr) \
} \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
*(pixptr).pul++ = source_pixel; \
break; \
case 16: \
*(pixptr).pus++ = (unsigned short)source_pixel; \
break; \
case 8: \
*(pixptr).pub++ = (UBYTE)source_pixel; \
break; \
default: \
*(pixptr).pub &= ~(pxscan).mask_array[(pxscan).bit_offset] ; \
*(pixptr).pub |= ((UBYTE)source_pixel << (pxscan).shift_array[(pxscan).bit_offset]) ; \
PXSCANBITI( pxrp, pxscan, pixptr ) \
break; \
} \
(pxscan).iCol += 1; \
} \
while(0)
#define PXSCANREADR(target_pixel, pxrp, pxscan, pixptr ) \
do \
{ \
if ((pxscan).iCol < 0) \
{ \
(pxscan).iCol = (pxrp).width-1; \
(pxscan).iRow += 1; \
PXSCANPOINT( pxrp, pxscan, pixptr, (pxscan).iCol, (pxscan).iRow ); \
} \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
(target_pixel) = *(pixptr).pul--; \
break; \
case 16: \
(target_pixel) = (unsigned short)*((pixptr).pus--); \
break; \
case 8: \
(target_pixel) = (UBYTE)*((pixptr).pub--); \
break; \
default: \
(target_pixel) = (*(pixptr).pub >> (pxscan).shift_array[(pxscan).bit_offset]) & (pxscan).read_mask; \
PXSCANBITD( pxrp, pxscan, pixptr ) \
} \
(pxscan).iCol -= 1; \
} \
while(0)
#define PXSCANWRITER( pxrp, pxscan, pixptr, source_pixel ) \
do \
{ \
if ((pxscan).iCol < 0) \
{ \
(pxscan).iCol = (pxrp).width-1; \
(pxscan).iRow += 1; \
PXSCANPOINT( pxrp, pxscan, pixptr, (pxscan).iCol, (pxscan).iRow ); \
} \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
*(pixptr).pul-- = source_pixel; \
break; \
case 16: \
*(pixptr).pus-- = (unsigned short)source_pixel; \
break; \
case 8: \
*(pixptr).pub-- = (UBYTE)source_pixel; \
break; \
default: \
*(pixptr).pub &= ~(pxscan).mask_array[(pxscan).bit_offset] ; \
*(pixptr).pub |= ((UBYTE)source_pixel << (pxscan).shift_array[(pxscan).bit_offset]) ; \
PXSCANBITD( pxrp, pxscan, pixptr ) \
} \
(pxscan).iCol -= 1; \
} \
while(0)
#define PXSCANREADD(target_pixel, pxrp, pxscan, pixptr ) \
do \
{ \
if ((pxscan).iRow < 0) \
{ \
(pxscan).iRow = (pxrp).height-1; \
PXSCANCOLI( pxrp, pxscan, pixptr ) \
} \
PXSCANRD(target_pixel, pxrp, pxscan, pixptr ) \
(pxscan).iRow -= 1; \
if ((pxscan).rows_increase) \
(pixptr).pub -= (pxscan).bytes_per_row; \
else \
(pixptr).pub += (pxscan).bytes_per_row; \
} \
while(0)
#define PXSCANWRITED(pxrp, pxscan, pixptr, source_pixel ) \
do \
{ \
if ((pxscan).iRow < 0) \
{ \
(pxscan).iRow = (pxrp).height-1; \
PXSCANCOLI( pxrp, pxscan, pixptr ) \
} \
PXSCANWR(pxrp, pxscan, pixptr, source_pixel ) \
(pxscan).iRow -= 1; \
if ((pxscan).rows_increase) \
(pixptr).pub -= (pxscan).bytes_per_row; \
else \
(pixptr).pub += (pxscan).bytes_per_row; \
} \
while(0)
#define PXSCANREADU(target_pixel, pxrp, pxscan, pixptr ) \
do \
{ \
if ((pxscan).iRow >= (pxrp).height) \
{ \
(pxscan).iRow = 0; \
PXSCANCOLI( pxrp, pxscan, pixptr ) \
} \
PXSCANRD(target_pixel, pxrp, pxscan, pixptr ) \
(pxscan).iRow += 1; \
if ((pxscan).rows_increase) \
(pixptr).pub += (pxscan).bytes_per_row; \
else \
(pixptr).pub -= (pxscan).bytes_per_row; \
} \
while(0)
#define PXSCANWRITEU(pxrp, pxscan, pixptr, source_pixel ) \
do \
{ \
if ((pxscan).iRow >= (pxrp).height) \
{ \
(pxscan).iRow = 0; \
PXSCANCOLI( pxrp, pxscan, pixptr ) \
} \
PXSCANWR(pxrp, pxscan, pixptr, source_pixel ) \
(pxscan).iRow += 1; \
if ((pxscan).rows_increase) \
(pixptr).pub += (pxscan).bytes_per_row; \
else \
(pixptr).pub -= (pxscan).bytes_per_row; \
} \
while(0)
#define PXSCANPOINT(pxrp, pxscan, pixptr, x, y) \
do \
{ \
UBYTE *qxy_prow; \
int qxy_ppb; \
\
if ((pxscan).rows_increase) \
qxy_prow = (pxrp).pixels + ((pxscan).bytes_per_row * (y)); \
else \
qxy_prow = (pxrp).pixels + \
((pxscan).bytes_per_row * ((pxrp).height - ((y)+1))); \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
(pixptr).pul = ((ULONG*)qxy_prow + (x)); \
break; \
case 16: \
(pixptr).pus = ((unsigned short*)qxy_prow + (x)); \
break; \
case 8: \
(pixptr).pub = (UBYTE*)qxy_prow + (x); \
break; \
default: \
qxy_ppb = (x) * (pxrp).bits_per_pixel; \
qxy_prow += ((pxrp).pack_unit/8) * (qxy_ppb / (pxrp).pack_unit); \
qxy_ppb %= (pxrp).pack_unit; \
(pxscan).unit_offset = qxy_ppb / 8; \
(pxscan).bit_offset = qxy_ppb % 8; \
if ((pxscan).always_increasing) \
(pixptr).pub = qxy_prow + (pxscan).unit_offset; \
else \
(pixptr).pub = qxy_prow + (pxscan).max_unit_offset - (pxscan).unit_offset; \
break; \
} \
(pxscan).iCol = x; \
(pxscan).iRow = y; \
(pxscan).colstart = (pixptr).pub; \
} \
while(0)
/**************************************************************************/
/**************************************************************************/
/********************** VI internal definitions ***************************/
/**************************************************************************/
/**************************************************************************/
#define PXSCANBITI( pxrp, pxscan, pixptr ) \
{ \
(pxscan).bit_offset += (pxrp).bits_per_pixel; \
if ((pxscan).bit_offset > 7) \
{ \
(pxscan).bit_offset = 0; \
if ((pxscan).always_increasing) \
++(pixptr).pub; \
else \
if ((pxscan).unit_offset++ < (pxscan).max_unit_offset) \
--(pixptr).pub; \
else \
{ \
(pxscan).unit_offset = 0; \
(pixptr).pub += (pxscan).unit_step; \
} \
} \
}
#define PXSCANBITD( pxrp, pxscan, pixptr ) \
{ \
(pxscan).bit_offset -= (pxrp).bits_per_pixel; \
if ((pxscan).bit_offset < 0) \
{ \
(pxscan).bit_offset = (pxscan).max_bit_offset; \
if ((pxscan).always_increasing) \
--(pixptr).pub; \
else \
if ((pxscan).unit_offset-- < 0) \
++(pixptr).pub; \
else \
{ \
(pxscan).unit_offset = (pxscan).max_bit_offset; \
(pixptr).pub -= (pxscan).unit_step; \
} \
} \
}
#define PXSCANWR(pxrp, pxscan, pixptr, source_pixel) \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
*(pixptr).pul = source_pixel; \
break; \
case 16: \
*(pixptr).pus = (unsigned short)source_pixel; \
break; \
case 8: \
*(pixptr).pub = (UBYTE)source_pixel; \
break; \
default: \
*(pixptr).pub &= ~(pxscan).mask_array[(pxscan).bit_offset] ; \
*(pixptr).pub |= ((UBYTE)source_pixel << (pxscan).shift_array[(pxscan).bit_offset]) ; \
break; \
}
#define PXSCANRD(target_pixel, pxrp, pxscan, pixptr) \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
(target_pixel) = *(pixptr).pul; \
break; \
case 16: \
(target_pixel) = (unsigned short)*(pixptr).pus; \
break; \
case 8: \
(target_pixel) = (UBYTE)*(pixptr).pub; \
break; \
default: \
(target_pixel) = (*(pixptr).pub >> (pxscan).shift_array[(pxscan).bit_offset]) & (pxscan).read_mask; \
break; \
}
#define PXSCANCOLI(pxrp, pxscan, pixptr) \
(pxscan).iCol += 1; \
(pixptr).pub = (pxscan).colstart; \
switch ((pxrp).bits_per_pixel) \
{ \
case 32: \
++(pixptr).pul; \
break; \
case 16: \
++(pixptr).pus; \
break; \
case 8: \
++(pixptr).pub; \
break; \
default: \
PXSCANBITI(pxrp, pxscan, pixptr) \
break; \
} \
(pxscan).colstart = (pixptr).pub;
#define PXSCANROWS(pxrp, pxscan, pixptr) \
(pxscan).iCol = 0; \
(pxscan).iRow += 1; \
(pxscan).bit_offset = 0; \
(pxscan).unit_offset = 0; \
if ((pxscan).rows_increase) \
(pixptr).pub = (pxrp).pixels + (pxscan).iRow * \
(pxscan).bytes_per_row; \
else \
(pixptr).pub = (pxrp).pixels + \
((pxrp).height - ((pxscan).iRow+1)) * (pxscan).bytes_per_row; \
(pixptr).pub += (pxscan).max_unit_offset;
/* "private" structures */
typedef struct
{
UBYTE mask_array[8];
UBYTE shift_array[8];
UBYTE read_mask;
int iCol, iRow;
int bytes_per_row;
int bit_offset;
int max_bit_offset;
int unit_offset;
int max_unit_offset;
int unit_step;
DV_BOOL always_increasing;
DV_BOOL rows_increase;
UBYTE *colstart;
} PIXSCAN;
typedef union
{
UBYTE *pub;
unsigned short *pus;
ULONG *pul;
} PIXPTR;
#endif /* VIPXRP */